;  PROGRAM:  CMD
;  VERSION:  1.0
;  DATE:  19 July 84
;  AUTHOR:  Richard Conn
;  PREVIOUS VERSIONS:  None
;
z3env	equ	0f400h
VERS	EQU	10		;version number

; CMD is copyright (c) 1984 by Richard Conn
; All Rights Reserved
; CMD may be used freely by the ZCPR3 Community

;
;	CMD is used to define and run a command line.  It either accepts
; the command line (including semicolons) which follow the verb CMD onto
; the command line buffer or, if no input is provided, it prompts the
; user for input and then places this into the command line buffer.
;
; Syntax:
;	CMD cmd1;cmd2;...
; or	CMD
;
; The sequence of commands "cmd1;cmd2;..." becomes the command line.
;

;
;  SYSLIB, Z3LIB, and VLIB References
;
	ext	z3init
	ext	getcl1,getcl2,puter2,putzex,dutdir
	ext	eprint,pafdc,cout,bline
	ext	retud
	ext	codend

;
;  Basic Definitions
;
TRUE	 EQU	0FFH		;define true and..
FALSE	 EQU	0       	;..false.

;
; System Addresses
;
OS$BASE EQU	000H		;system base..
BDOS	EQU	OS$BASE+05H
FCB	EQU	OS$BASE+5CH
FCB2	EQU	OS$BASE+6CH
TBUFF	EQU	OS$BASE+80H
TPA	EQU	OS$BASE+100H

;
;  ASCII Chars
;
LF	EQU	0AH		;..linefeed..
CR	EQU	0DH		;..carriage return..

;
; Environment Definition
;
	if	z3env ne 0
;
; External ZCPR3 Environment Descriptor
;
	jmp	start
	db	'Z3ENV'	;This is a ZCPR3 Utility
	db	1	;External Environment Descriptor
z3eadr:
	dw	z3env
start:
	lhld	z3eadr	;pt to ZCPR3 environment
;
	else
;
; Internal ZCPR3 Environment Descriptor
;
	MACLIB	Z3BASE.LIB
	MACLIB	SYSENV.LIB
z3eadr:
	jmp	start
	SYSENV
start:
	lxi	h,z3eadr	;pt to ZCPR3 environment
	endif

;
; Mainline
;
	call	z3init		;initialize the ZCPR3 Env

;
; Check for Help or Prompt
;
	lda	fcb+1		;check for help request
	cpi	' '		;prompted input?
	jz	prompt
	cpi	'/'		;help?
	jnz	cinit
;
; Print Help Message
;
help:
	call	eprint
	db	'CMD, Version '
	db	(VERS/10)+'0','.',(VERS MOD 10)+'0'
	db	cr,lf,' Syntax:  CMD cmd1;cmd2;... or CMD (prompted input)'
	db	cr,lf,' CMD defines the command line in the CL buffer'
	db	0
	ret
;
; Initialize Command Line
;
cinit:
	call	getcl1		;check for command line buffer
	jz	nocl
;
; HL now points to the command line buffer
;
	call	codend		;pt to free area
	inx	h		;skip 2 bytes
	inx	h
	xchg			;... in DE
	lxi	h,tbuff+2	;pt to option input
	call	copystr		;copy string
	mvi	c,1		;set not empty
;
; Entry point to build rest of command line, where DE=next address
;   and C=empty line flag (C=0 means line was empty)
;
checkcl:
	mov	a,c		;get empty flag
	call	puter2		;set error flag
	call	getcl2		;get address of command line
	jz	setsh		;set shell command
	call	copystr		;copy string
setsh:
	call	getcl1		;pt to command line buffer
	xchg			;... in DE
	lxi	h,4		;pt to first char position
	dad	d
	shld	lstart		;save start address in case of abort
	xchg
	mov	m,e		;store pointer
	inx	h
	mov	m,d
	inx	h		;pt to buffer size
	mov	b,m		;get it in B
	call	codend		;pt to string
	inx	h		;skip 2 bytes
	inx	h
clcopy:
	mov	a,m		;get char
	stax	d		;put char
	inx	h		;pt to next
	inx	d
	ora	a		;done?
	rz
	dcr	b		;count down
	jnz	clcopy
;
; Command Line Too Long
;
	lhld	lstart		;zero command line
	mvi	m,0
	call	eprint
	db	' Command Line too Long for Buffer',0
	ret

;
; Print no command line buffer message and exit
;
nocl:
	call	eprint
	db	' No Command Line Buffer',0
	ret

;
; Copy string from HL to DE
;   Store ending 0 and leave pointer in DE to it
;
copystr:
	mov	a,m		;get char
	stax	d		;store it
	ora	a		;done?
	rz
	inx	h		;pt to next
	inx	d
	jmp	copystr

;
; Prompt User for Input
;
prompt:
	call	eprint
	db	'CMD ',0
	call	retud		;get DU
;
; Print DU
;
	mov	a,b		;output disk
	adi	'A'
	call	cout
	mov	a,c		;output user
	call	pafdc
	mvi	a,':'		;separator
	call	cout
;
; Print DIR
;
	call	dutdir		;convert to name
	jz	prompt2		;no name input
;
; DIR is defined
;
	mvi	b,8		;8 chars max
prompt1:
	mov	a,m		;get char
	cpi	' '		;done if space
	jz	promptx
	call	cout		;echo it
	inx	h		;pt to next
	dcr	b		;count down
	jnz	prompt1
	jmp	promptx
;
; DIR is not defined
;
prompt2:
	call	eprint		;name not found
	db	'Noname',0
;
; Complete prompt and get user input
;
promptx:
	call	eprint
	db	'> ',0
	mvi	a,1		;tell ZEX that it is prompted
	call	putzex
	call	codend		;use buffer area
	mvi	m,254		;set large line size
	mvi	a,0		;no caps
	call	bline		;get input line
	xra	a		;no more prompt
	call	putzex
	call	codend		;skip to EOL
	inx	h
	inx	h
	xchg			;ptr in DE
	ldax	d		;get first char
	mov	c,a		;save flag
;
; Skip to end of input line
;
findeol:
	ldax	d		;get char
	ora	a		;done?
	jz	checkcl
	inx	d		;pt to next
	jmp	findeol
;
; Buffers
;
lstart:
	ds	2		;start of command line

	end
